<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <style>
      #app {
        width: 300px;
        height: 400px;
        border: 1px solid cyan;
        position: relative;
      }
      ul {
        padding: 0;
      }
      li {
        display: flex;
        padding: 3px 7px;
        width: 200px;
        height: 30px;
      }
      .cart {
        width: 100px;
        height: 100px;
        position: absolute;
        bottom: 0;
        right: 0;
        background-color: rgba(255, 0, 0, 0.4);
      }
      .animate {
        width: 200px;
        height: 30px;
        position: absolute;
        border: 1px solid red;
        transition: 1s linear;
      }
    </style>
  </head>
  <body>
    <div id="app">
      <ul>
        <li v-for="(product, index) in products" :key="product.id" ref="lis">
          <span class="name">{{ product.name }}</span>
          <button @click="addToCart(index)">Add To Cart</button>
        </li>
      </ul>
      <transition @enter="enter" @after-enter="afterEnter">
        <div class="animate" v-if="isShow"></div>
      </transition>
      <div class="cart" ref="cart"></div>
    </div>
  </body>
  <script src="./node_modules/vue/dist/vue.js"></script>
  <script>
    const vm = new Vue({
      el: '#app',
      data() {
        return {
          isShow: false,
          currentIndex: -1,
          products: [
            {
              id: 1,
              name: 'iPhone'
            },
            {
              id: 2,
              name: 'iPad'
            },
            {
              id: 3,
              name: 'Mac'
            }
          ]
        }
      },
      methods: {
        addToCart(index) {
          this.currentIndex = index
          this.isShow = true
        },
        enter(el, done) {
          const li = this.$refs.lis[this.currentIndex]
          const { x, y } = li.getBoundingClientRect()
          el.style.left = x + 'px'
          el.style.top = y + 'px'

          const { x: cartX, y: cartY } = this.$refs.cart.getBoundingClientRect()
          el.style.transform = `translate3d(${cartX - x}px, ${
            cartY - y
          }px, 0) scale(0,0)`

          el.addEventListener('transitionend', done)
        },
        afterEnter(el) {
          this.isShow = false
        }
      }
    })
  </script>
</html>
